<?php
declare(strict_types=1);

namespace WebApp\lib\db;

use ErrorException;
use txz\common\base\utils\LogHelper;
use txz\common\third_lib\model\conf\MyPostgres;
use WebApp\lib\db\postgres\CoTable;
use WebApp\lib\util\Util;

/**
 * Class Table
 * @package txz\common\third_lib\model\lib
 */
class PgTable extends AbstractTable
{
    private $m_db = null;

    /**
     * @param $server
     * @param $dbName
     * @param $tableName
     * @param string $pre
     * @param string $suffix
     * @return mixed
     */
    public function process($server, $dbName, $tableName, $pre = '', $suffix = ''): void
    {
        $this->setPre($pre);
        $this->setSuffix($suffix);
        $this->setDbName($dbName);
        $this->setServerName($server);
        $this->setTableName(
            ($pre ? $pre . '_' : '') .
            $tableName .
            ($suffix ? '_' . $suffix : '')
        );

        $this->setDb(new CoTable());
    }


    /**
     * @return string
     */
    public function getLastSql(): string
    {
        return $this->getDb()->getLastSql();
    }

    /**
     * @return string
     */
    public function getLastErr(): string
    {
        return $this->getDb()->getLastErr();
    }

    /**
     * @return string
     */
    public function getLast(): string
    {
        return $this->getDb()->getLastSql();
    }

    /**
     * @param string $str
     * @return string
     */
    public function escapeString(string $str)
    {
        return addslashes($str);
    }

    /**
     * @param string $m_sql
     * @return mixed
     */
    public function execute(string $m_sql)
    {
        return $this->getPool()->exec($this->getDb()->execute($m_sql), $this);
    }

    /**
     * 函数的含义说
     *
     * @param string $need [参数一的说明1]
     * @param array $where 参数一的说明2
     * @param string $group 参数一的说明3
     * @param string $sort 参数一的说明4
     * @return mixed
     */
    public function getObj($need = '', $where = [], $group = '', $sort = '')
    {
        try {
            if (!$this->getTableName()) {
                throw new ErrorException('no table');
            }

            return $this->getPool()->exec(
                $this->getDb()->getObj(
//                    $this->getDbName() . '.' . $this->getTableName(),
                    $this->getTableName(),
                    $need,
                    $where,
                    $group,
                    $sort
                ),
                $this
            );
        } catch (ErrorException $e) {
            LogHelper::logE($e->getMessage());
            return false;
        }
    }

    /**
     * @param string $need
     * @param array $where
     * @param string $group
     * @param string $sort
     * @param string $limit
     * @return mixed
     */
    public function getObjArr($need = '', $where = [], $group = '', $sort = '', $limit = '')
    {
        try {
            if (!$this->getTableName()) {
                throw new ErrorException('no table');
            }
            $arr = $this->getPool()->exec($this->getDb()->getObjArr(
//                $this->getDbName() . '.' . $this->getTableName(),
                $this->getTableName(),
                $need,
                $where,
                $group,
                $sort,
                $limit
            ), $this);
        } catch (ErrorException $e) {
            LogHelper::logE($e->getMessage());
            return false;
        }

        return $arr;
    }

    /**
     * @param array $where
     * @return int
     */
    public function getObjCount($where = [])
    {
        try {
            if (!$this->getTableName()) {
                throw new ErrorException('no table');
            }

            return $this->getPool()->exec(
//                $this->getDb()->getObjCount($this->getDbName() . '.' . $this->getTableName(), $where),
                $this->getDb()->getObjCount($this->getTableName(), $where),
                $this
            );
        } catch (ErrorException $e) {
            LogHelper::logE($e->getMessage());
            return false;
        }
    }

    /**
     * @param array $data
     * @return bool
     */
    public function addObj($data = [])
    {
        try {
            if (!$this->getTableName()) {
                throw new ErrorException('no table');
            }

            if (!$data) {
                throw new ErrorException('no set');
            }

            return $this->getPool()->exec(
//                $this->getDb()->addObj($this->getDbName() . '.' . $this->getTableName(), $data),
                $this->getDb()->addObj($this->getTableName(), $data),
                $this
            );
        } catch (ErrorException $e) {
            LogHelper::logE($e->getMessage());
            return false;
        }
    }

    /**
     * @param array $data
     * @return bool
     */
    public function replaceObj($data = [])
    {
        try {
            if (!$this->getTableName()) {
                throw new ErrorException('no table');
            }

            if (!$data) {
                throw new ErrorException('no set');
            }

            return $this->getPool()->exec(
//                $this->getDb()->replaceObj($this->getDbName() . '.' . $this->getTableName(), $data),
                $this->getDb()->replaceObj($this->getTableName(), $data),
                $this
            );
        } catch (ErrorException $e) {
            LogHelper::logE($e->getMessage());
            return false;
        }
    }

    /**
     * @param array $where
     * @return bool
     */
    public function removeObj($where = [])
    {
        try {
            if (!$this->getTableName()) {
                throw new ErrorException('no table');
            }

            if (!$where) {
                throw new ErrorException('no where');
            }

            return $this->getPool()->exec(
//                $this->getDb()->removeObj($this->getDbName() . '.' . $this->getTableName(), $where),
                $this->getDb()->removeObj($this->getTableName(), $where),
                $this
            );
        } catch (ErrorException $e) {
            LogHelper::logE($e->getMessage());
            return false;
        }
    }

    /**
     * @param array $data
     * @param array $where
     * @return bool
     */
    public function updateObj($data = [], $where = [])
    {
        try {
            if (!$this->getTableName()) {
                throw new ErrorException('no table');
            }

            if (!$data) {
                throw new ErrorException('no data');
            }

            if (!$where) {
                throw new ErrorException('no where');
            }

            return $this->getPool()->exec(
//                $this->getDb()->updateObj($this->getDbName() . '.' . $this->getTableName(), $data, $where),
                $this->getDb()->updateObj($this->getTableName(), $data, $where),
                $this
            );
        } catch (ErrorException $e) {
            LogHelper::logE($e->getMessage());
            return false;
        }
    }

    /**
     * @param $sql
     * @return mixed
     */
    public function getObjBySql($sql)
    {
        return $this->getPool()->exec(
            $this->getDb()->getObjBySql($sql),
            $this
        );
    }

    /**
     * @param $sql
     * @return array
     */
    public function getObjArrBySql(string $sql)
    {
        return $this->getPool()->exec(
            $this->getDb()->getObjArrBySql($sql),
            $this
        );
    }

    /**
     * @param $arr
     * @return bool
     * @internal param $call_back
     */
    public function transaction(...$arr): bool
    {
        if (is_array($arr[0])) {
            $arr = $arr[0];
        }
        return $this->getPool()->exec(
            $this->getDb()->transaction($arr),
            $this
        );
    }

    /**
     * @return MyPostgres
     */
    public function getPool(): MyPostgres
    {
//        $key = 'pgPool.' . $this->getServerName() . '.' . Util::get_pid();
        $key = 'pgPool.' . $this->getDbName() . '.' . Util::get_pid();
        if (!isset($GLOBALS[$key])) {
            $GLOBALS[$key] = new MyPostgres($this->getDbName());
        }
        return $GLOBALS[$key];
    }

    /**
     * @return CoTable
     */
    public function getDb()
    {
        return $this->m_db;
    }

    /**
     * @param CoTable $db
     */
    public function setDb($db)
    {
        $this->m_db = $db;
    }
}
